package com.dw.etl.core.service;

import com.dw.etl.common.base.mapper.BaseMapper;
import com.dw.etl.common.util.SnowflakeIdWorker;
import com.dw.etl.common.util.UUIDUtil;
import com.dw.etl.common.vo.PaginationVO;
import com.dw.etl.core.api.*;
import com.dw.etl.core.bean.model.*;
import com.dw.etl.core.bean.vo.LayMsg;
import com.dw.etl.core.bean.vo.MdMedDmtbVO;
import com.dw.etl.core.config.EtlConstant;
import com.dw.etl.core.mapper.MdMedDmtbMapper;
import com.dw.etl.core.utils.EtlUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;

/**
 * mdMedDmtb服务实现类
 * Created by hozeData on 2021/07/13.
 */
@Service
@Transactional
public class MdMedDmtbServiceImpl implements MdMedDmtbService{

    private static final Logger LOGGER = LoggerFactory.getLogger(MdMedDmtbServiceImpl.class);

    @Autowired
    private MdMedDmtbMapper mdMedDmtbMapper;

    @Override
    public int insert(MdMedDmtb mdMedDmtb) {
        if(StringUtils.isEmpty(mdMedDmtb.getIdDmtb())){
            String uuid32 = UUIDUtil.getUUID32();
            mdMedDmtb.setIdDmtb(uuid32);
        }
        return mdMedDmtbMapper.insert(mdMedDmtb);
    }

    @Override
    public int insertSelective(MdMedDmtb mdMedDmtb)  {
        if(StringUtils.isEmpty(mdMedDmtb.getIdDmtb())){
            String uuid32 = UUIDUtil.getUUID32();
            mdMedDmtb.setIdDmtb(uuid32);
        }
        return mdMedDmtbMapper.insertSelective(mdMedDmtb);
    }

    @Override
    public int deleteById(String idDmtb)  {
        return mdMedDmtbMapper.deleteByPrimaryKey(idDmtb);
    }

    @Override
    public int updateByIdSelective(MdMedDmtb mdMedDmtb)  {

        return mdMedDmtbMapper.updateByPrimaryKeySelective(mdMedDmtb);
    }

    @Override
    public int updateById(MdMedDmtb mdMedDmtb)  {
        return mdMedDmtbMapper.updateByPrimaryKey(mdMedDmtb);
    }

    @Override
    public MdMedDmtb getById(String idDmtb)  {
        return mdMedDmtbMapper.selectByPrimaryKey(idDmtb);
    }

    @Override
    public List<MdMedDmtb> findByModel(MdMedDmtb mdMedDmtb)  {
        return mdMedDmtbMapper.findByModel(mdMedDmtb);
    }

    @Override
    public PaginationVO<MdMedDmtb> findPageByModel(MdMedDmtb mdMedDmtb, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum == null? 1 : pageNum, pageSize == null? 10 : pageSize);
        List<MdMedDmtb> quesList = mdMedDmtbMapper.findByModel(mdMedDmtb);
        PageInfo<MdMedDmtb> pageInfo = new PageInfo<>(quesList);
        PaginationVO<MdMedDmtb> paginationVo = new PaginationVO(pageInfo.getTotal(), pageInfo.getList());
        return paginationVo;
    }

    @Override
    public PaginationVO<MdMedDmtb> findPageByLike(String filter, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum == null? 1 : pageNum, pageSize == null? 10 : pageSize);
        List<MdMedDmtb> quesList = mdMedDmtbMapper.findByLike(filter);
        PageInfo<MdMedDmtb> pageInfo = new PageInfo<>(quesList);
        PaginationVO<MdMedDmtb> paginationVo = new PaginationVO(pageInfo.getTotal(), pageInfo.getList());
        return paginationVo;
    }

    @Override
    public List<Map<String, Object>> findAllIndex() {
        return mdMedDmtbMapper.findAllIndex();
    }

    @Override
    public MdMedDmtb getTbByIndex(String idIndex) {
        MdMedDmtb dmtb = new MdMedDmtb();
        dmtb.setCdDimgrp(EtlConstant.CD_DIM_GROUP_DEF);
        dmtb.setIdIndex(idIndex);
        List<MdMedDmtb> list = mdMedDmtbMapper.findByModel(dmtb);
        if(list.size()>0) {
            dmtb = list.get(0);
        } else {
            dmtb = null;
        }
        return dmtb;
    }

    @Autowired
    MdMedTbService mdMedTbService;
    @Autowired
    MdMedTbFldService mdMedTbFldService;
    @Autowired
    BaseDbTpcompService baseDbTpcompService;
    @Autowired
    MdMedDimService mdMedDimService;
    @Autowired
    MdBaseIndexService mdBaseIndexService;
    @Autowired
    BaseMapper baseMapper;
    @Value("${etl.main.datasource.type}")
    private String dbType;

    @Override
    public LayMsg save(MdMedDmtbVO mdMedDmtbVO) {
        List<MdMedTbFld> medTbFldList = mdMedTbFldService.findTbDimField(mdMedDmtbVO.getIdTb());
        List<String> fldDimList = mdMedDmtbVO.getFldDimList();
        List<MdMedTbFld> needFldList = new ArrayList<>();
        String idIndex = mdMedDmtbVO.getIdIndex();
        for(String fld:fldDimList) {
            for(MdMedTbFld tbFld:medTbFldList) {
                if(fld.equals(tbFld.getIdPubfld())) {
                    needFldList.add(tbFld);
                    break;
                }
            }
        }
        MdBaseIndex index = mdBaseIndexService.getById(idIndex);
        MdMedDmtb dmtb = new MdMedDmtb();
        dmtb.setIdIndex(idIndex);
        dmtb.setCdDimgrp(mdMedDimService.getCdDimgrp(fldDimList));
        LayMsg layMsg = createDmTable(needFldList,dmtb);
        return layMsg;
    }

    @Override
    public LayMsg createDmTable(List<MdMedTbFld> medTbFldList, MdMedDmtb dmtb){
        List<MdMedDmtb> list = this.findByModel(dmtb);
        if(list.size()>0) {
            return LayMsg.fail().addMsg("请勿重复添加指标维度表");
        }
        if(medTbFldList.size()<1) {
            return LayMsg.fail().addMsg("无可添加字段");
        }
        MdBaseIndex index = mdBaseIndexService.getById(dmtb.getIdIndex());
        Set<String> dimFldSet = new HashSet<>();
        String idPubfld;
        String tableName = "dm_"+ SnowflakeIdWorker.getId();
        dmtb.setNaIndex(index.getNa());
        dmtb.setFgAct(true);
        dmtb.setIdDmtb(UUIDUtil.getUUID32());
        dmtb.setIdTb(tableName);
        this.insert(dmtb);
        List<BaseDbTpcomp> dbTpcompList = baseDbTpcompService.findByDbType(dbType);
        StringBuffer createTableSql = new StringBuffer("create table "+tableName+"( pk "+ EtlUtil.getDbTypeByStandType(dbTpcompList,"NUMBER",19L,0)+" primary key,");
        createTableSql.append("id_index "+EtlUtil.getDbTypeByStandType(dbTpcompList,"STRING",100L,0)+",");
        createTableSql.append("na_index "+EtlUtil.getDbTypeByStandType(dbTpcompList,"STRING",100L,0)+",");
        createTableSql.append("value "+EtlUtil.getDbTypeByStandType(dbTpcompList,"NUMBER",index.getNumLth(),index.getNumPrec())+",");
        createTableSql.append("dim_day_occur "+EtlUtil.getDbTypeByStandType(dbTpcompList,"STRING",8L,index.getNumPrec())+",");
        boolean flagCreate = false;
        MdMedTb medTb = new MdMedTb();
        medTb.setIdTb(tableName);
        medTb.setCd(tableName);
        medTb.setNa("指标"+dmtb.getNaIndex()+"统计表");
        medTb.setSdTbca("DM");
        for(MdMedTbFld fld:medTbFldList) {
            idPubfld = fld.getIdPubfld();
            if(!dimFldSet.contains(idPubfld)) {
                flagCreate = true;
                createTableSql.append(idPubfld+" "+EtlUtil.getDbTypeByStandType(dbTpcompList,fld.getEuTp(),fld.getNumLth(),fld.getNumPrec())+",");
                dimFldSet.add(idPubfld);
                try {
                    fld.setIdTbFld(UUIDUtil.getUUID32());
                    fld.setIdTb(tableName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if(flagCreate) {
            createTableSql.append("dt_sys_cre date,dt_sys_modi date)");
            addCommonDmMedTbFldList(tableName,index,medTbFldList);
            baseMapper.execDdlSql(createTableSql.toString());
            mdMedTbService.insert(medTb);
            mdMedTbFldService.save(medTbFldList);
        }
        return LayMsg.fail().addMsg("表已创建");
    }

    private void addCommonDmMedTbFldList(String tableName,MdBaseIndex index ,List<MdMedTbFld> medTbFldList) {
        MdMedTbFld medTbFld = new MdMedTbFld();
        medTbFld.setIdTb(tableName);
        medTbFld.setIdTbFld(UUIDUtil.getUUID32());
        medTbFld.setIdPubfld("pk");
        medTbFld.setEuTp("NUMBER");
        medTbFld.setNumLth(19L);
        medTbFld.setNumPrec((byte)0);
        medTbFld.setFgAct((byte)1);
        medTbFld.setNa("主键");
        medTbFldList.add(medTbFld);
        medTbFld = new MdMedTbFld();
        medTbFld.setIdTb(tableName);
        medTbFld.setIdTbFld(UUIDUtil.getUUID32());
        medTbFld.setIdPubfld("id_index");
        medTbFld.setEuTp("STRING");
        medTbFld.setNumLth(100L);
        medTbFld.setNumPrec((byte)0);
        medTbFld.setNa("指标主键");
        medTbFldList.add(medTbFld);
        medTbFld = new MdMedTbFld();
        medTbFld.setIdTb(tableName);
        medTbFld.setIdTbFld(UUIDUtil.getUUID32());
        medTbFld.setIdPubfld("na_index");
        medTbFld.setEuTp("STRING");
        medTbFld.setNumLth(100L);
        medTbFld.setNumPrec((byte)0);
        medTbFld.setNa("指标编码");
        medTbFldList.add(medTbFld);
        medTbFld = new MdMedTbFld();
        medTbFld.setIdTb(tableName);
        medTbFld.setIdTbFld(UUIDUtil.getUUID32());
        medTbFld.setIdPubfld("value");
        medTbFld.setEuTp("NUMBER");
        medTbFld.setNumLth(index.getNumLth());
        medTbFld.setNumPrec(index.getNumPrec());
        medTbFld.setNa("值");
        medTbFldList.add(medTbFld);
        medTbFld = new MdMedTbFld();
        medTbFld.setIdTb(tableName);
        medTbFld.setIdTbFld(UUIDUtil.getUUID32());
        medTbFld.setIdPubfld("dim_day_occur");
        medTbFld.setEuTp("NUMBER");
        medTbFld.setNumLth(index.getNumLth());
        medTbFld.setNumPrec(index.getNumPrec());
        medTbFld.setNa("日期-天");
        medTbFldList.add(medTbFld);
    }
}
